﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DormMS.Model;
using DormMS.IService;
using DormMS.Model.SearchModels;
using Infrastructure.Dao;
using SqlSugar;
using DormMS.Model.ViewModels;
using Infrastructure;
using DormMS.Model.Enum;

namespace DormMS.Service
{
    public class MemberService : IMemberService
    {
        private SqlSugarClient db;

        #region 会员
        /// <summary>
        /// 分页获取会员列表
        /// </summary>
        /// <param name="search"></param>
        /// <param name="total"></param>
        /// <returns></returns>
        public List<V_Member> GetMemberList(MemberSearchModel search, ref int total)
        {
            using (db = DbConfig.GetInstance())
            {
                db.CurrentFilterKey = "FalseDelteJoin";
                
                search.OrderByFields = "m." + search.OrderByFields;
                var data = db.Queryable<Member>().JoinTable<MemberLevel>((m, s2) => m.MemberLevel == s2.Id);
                if (!search.Keywords.IsNullOrEmpty())
                {
                    data = data.Where(m => m.NickName.Contains(search.Keywords));
                }
                if (search.MemberLevel > 0)
                {
                    data = data.Where(m => m.MemberLevel == search.MemberLevel);
                }

                var list = data.Select<Member, MemberLevel, V_Member>((m, s2) => new V_Member { Id = m.Id, NickName = m.NickName, AddTime=m.AddTime, Sex = m.Sex, Balance = m.Balance, Mobile = m.Mobile, MemberLevel = m.MemberLevel, LevelDes = s2.LevelName, Points = m.Points, Avatar = m.Avatar, Birthday = m.Birthday })
                    .OrderBy(search.OrderByFields).ToPageList(search.Skip / search.Take + 1, search.Take, ref total);
                return list;
            }
        }
        /// <summary>
        /// 获取会员信息
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public Member GetMemberInfo(int Id)
        {
            using (db = DbConfig.GetInstance())
            {
                var model = db.Queryable<Member>().SingleOrDefault(t => t.Id == Id);
                return model;
            }
        }

        public V_Member GetV_Member(int Id)
        {
            using (db = DbConfig.GetInstance())
            {
                db.CurrentFilterKey = "FalseDelteJoin";
                var model = db.SqlQuery<V_Member>("select m.*,s1.LevelName as LevelDes from Member m inner join MemberLevel s1 on m.MemberLevel=s1.Id where m.Id=" + Id).SingleOrDefault();
                return model;
            }
        }

        /// <summary>
        /// 获取会员信息
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public Member GetMemberInfo(string where)
        {
            using (db = DbConfig.GetInstance())
            {
                var model = db.Queryable<Member>().Where(where).FirstOrDefault();
                return model;
            }
        }

        /// <summary>
        /// 获取会员列表
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public List<Member> GetMemberInfoList(string where)
        {
            using (db = DbConfig.GetInstance())
            {
                var model = db.Queryable<Member>().Where(where).OrderBy(t=>t.NickName).ToList();
                return model;
            }
        }
        /// <summary>
        /// 修改会员
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool EditMember(Member model)
        {
            using (db = DbConfig.GetInstance())
            {
                return db.Update<Member>(model);
            }
        }

        /// <summary>
        /// 增加会员
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int AddMember(Member model)
        {
            using (db = DbConfig.GetInstance())
            {
                return db.Insert<Member>(model).ObjToInt();
            }
        }

        #endregion

        #region 会员等级
        /// <summary>
        /// 获取会员等级列表
        /// </summary>
        /// <returns></returns>
        public List<MemberLevel> GetMemberLevelList()
        {
            using (db = DbConfig.GetInstance())
            {
                var list = db.GetList<MemberLevel>("select * from MemberLevel where IsDeleted=0 order by Id");
                return list;
            }
        }


        public MemberLevel GetMemberLevelInfo(int Id)
        {
            using (db = DbConfig.GetInstance())
            {
                var model = db.Queryable<MemberLevel>().SingleOrDefault(t => t.Id == Id);
                return model;
            }
        }

        public bool EditMemberLevel(MemberLevel model)
        {
            using (db = DbConfig.GetInstance())
            {
                return db.Update<MemberLevel>(model);
            }
        }
        #endregion

        #region 会员地址
        public List<MemberAddress> GetMemberAdressList(int memberId)
        {
            using (db = DbConfig.GetInstance())
            {
                return db.Queryable<MemberAddress>().Where(t => t.MemberId == memberId).OrderBy(t => t.AddTime, OrderByType.Desc).ToList();
            }
        }

        public List<V_MemberAddress> GetV_MemberAdressList(int memberId)
        {
            using (db = DbConfig.GetInstance())
            {
                var model = db.Queryable<MemberAddress>().JoinTable<Common_Area>((m, a1) => m.Province == a1.Id).JoinTable<Common_Area>((m, a2) => m.City == a2.Id).JoinTable<Common_Area>((m, a3) => m.District == a3.Id)
                    .Where(m => m.MemberId == memberId).Select<MemberAddress, Common_Area, Common_Area, Common_Area, V_MemberAddress>((m, a1, a2, a3) =>
                         new V_MemberAddress { Id = m.Id, Address = m.Address, Mobile = m.Mobile, Consignee = m.Consignee, Province = m.Province, ProvinceName = a1.Name, City = m.City, CityName = a2.Name, District = m.District, DistrictName = a3.Name, IsDefault = m.IsDefault }).ToList();
                return model;
            }
        }

        public List<V_MemberAddress> GetV_MemberAdressList(AddressSearchModel search,ref int total)
        {
            using (db = DbConfig.GetInstance())
            {
                var model = db.Queryable<MemberAddress>().JoinTable<Common_Area>((m, a1) => m.Province == a1.Id).JoinTable<Common_Area>((m, a2) => m.City == a2.Id).JoinTable<Common_Area>((m, a3) => m.District == a3.Id)
                    .Where(m => m.MemberId == search.MemberId.Value).Select<MemberAddress, Common_Area, Common_Area, Common_Area, V_MemberAddress>((m, a1, a2, a3) =>
                         new V_MemberAddress { Id = m.Id, Address = m.Address, Mobile = m.Mobile, Consignee = m.Consignee, Province = m.Province, ProvinceName = a1.Name, City = m.City, CityName = a2.Name, District = m.District, DistrictName = a3.Name, IsDefault = m.IsDefault }).OrderBy(m=>m.AddTime,OrderByType.Desc).ToPageList(search.Skip / search.Take + 1, search.Take, ref total);

                return model;
            }
        }


        public MemberAddress GetMemberAddress(int Id)
        {
            using (db = DbConfig.GetInstance())
            {
                return db.Queryable<MemberAddress>().SingleOrDefault(t => t.Id == Id);
            }
        }

        public V_MemberAddress GetV_MemberAddress(int Id)
        {
            using (db = DbConfig.GetInstance())
            {
                var model = db.Queryable<MemberAddress>().JoinTable<Common_Area>((m, a1) => m.Province == a1.Id).JoinTable<Common_Area>((m, a2) => m.City == a2.Id).JoinTable<Common_Area>((m, a3) => m.District == a3.Id)
                    .Where(m => m.Id == Id).Select<MemberAddress, Common_Area, Common_Area, Common_Area, V_MemberAddress>((m, a1, a2, a3) =>
                         new V_MemberAddress { Id = m.Id, Address = m.Address, Mobile = m.Mobile, Consignee = m.Consignee, Province = m.Province, ProvinceName = a1.Name, City = m.City, CityName = a2.Name, District = m.District, DistrictName = a3.Name, IsDefault = m.IsDefault }).FirstOrDefault();
                return model;
            }
        }

        /// <summary>
        /// 获取会员默认地址
        /// </summary>
        /// <param name="memberId"></param>
        /// <returns></returns>
        public V_MemberAddress GetDefaultAddress(int memberId)
        {
            using (db = DbConfig.GetInstance())
            {
                var model = db.Queryable<MemberAddress>().JoinTable<Common_Area>((m, a1) => m.Province == a1.Id).JoinTable<Common_Area>((m, a2) => m.City == a2.Id).JoinTable<Common_Area>((m, a3) => m.District == a3.Id)
                    .Where(m => m.MemberId == memberId).OrderBy(m=>m.IsDefault,OrderByType.Desc).OrderBy(m=>m.AddTime,OrderByType.Desc).Select<MemberAddress, Common_Area, Common_Area, Common_Area, V_MemberAddress>((m, a1, a2, a3) =>
                         new V_MemberAddress { Id = m.Id, Address = m.Address, Mobile = m.Mobile, Consignee = m.Consignee, Province = m.Province, ProvinceName = a1.Name, City = m.City, CityName = a2.Name, District = m.District, DistrictName = a3.Name, IsDefault = m.IsDefault }).FirstOrDefault();
                return model;
            }
        }

        public void AddMemberAddress(MemberAddress model)
        {
            using (db = DbConfig.GetInstance())
            {
                if (model.IsDefault)
                {
                    var list = db.Queryable<MemberAddress>().Where(t => t.MemberId == model.MemberId).ToList();
                    foreach (var item in list)
                    {
                        item.IsDefault = false;
                    }
                    db.UpdateRange<MemberAddress>(list);
                }
                db.Insert<MemberAddress>(model);
            }
        }

        public void EditMemberAddress(MemberAddress model)
        {
            using (db = DbConfig.GetInstance())
            {
                if (model.IsDefault)
                {
                    var list = db.Queryable<MemberAddress>().Where(t => t.MemberId == model.MemberId).ToList();
                    foreach (var item in list)
                    {
                        item.IsDefault = false;
                    }
                    db.UpdateRange<MemberAddress>(list);
                }
                db.Update<MemberAddress>(model);
            }
        }

        public void DelMemberAddress(int Id)
        {
            using (db = DbConfig.GetInstance())
            {
                db.Delete<MemberAddress>("Id=" + Id);
            }
        }

        #endregion


        #region 会员充值

        /// <summary>
        /// 分页获取会员充值记录
        /// </summary>
        /// <param name="search"></param>
        /// <param name="total"></param>
        /// <returns></returns>
        public List<V_MemberRecharge> GetMemberRechargeList(RechargeSearchModel search, ref int total)
        {
            using (db = DbConfig.GetInstance())
            {
                db.CurrentFilterKey = "";
                var data = db.Queryable<MemberRecharge>().JoinTable<Member>((m,s)=>m.MemberId==s.Id).Where("m.Status=1 and m.IsDeleted=0 and s.IsDeleted=0");

                if (search.MemberId.HasValue)
                {
                    data = data.Where(m => m.MemberId == search.MemberId.Value);
                }
                if (!search.KeyWord.IsNullOrEmpty())
                {
                    data = data.Where("s.NickName like '%" + search.KeyWord + "%'");
                }
                if (search.BeginTime.HasValue && search.EndTime.HasValue)
                {
                    data = data.Where(m=>m.AddTime>search.BeginTime&&m.AddTime<search.EndTime);
                }

                return data.Select<MemberRecharge, Member, V_MemberRecharge>((m,s)=>new V_MemberRecharge { Id=m.Id,Status=m.Status,Amount=m.Amount,NickName=s.NickName,PayNo=m.PayNo,PayTime=m.PayTime,MemberId=m.MemberId})
                    .OrderBy(m => m.AddTime, OrderByType.Desc).ToPageList(search.Skip / search.Take + 1, search.Take, ref total);
            }
        }


        public int AddMemberRecharge(MemberRecharge model)
        {
            using (db = DbConfig.GetInstance())
            {
                return db.Insert<MemberRecharge>(model).ObjToInt();
            }
        }

        public MemberRecharge GetMemberRecharge(int Id)
        {
            using (db = DbConfig.GetInstance())
            {
                return db.Queryable<MemberRecharge>().SingleOrDefault(t => t.Id == Id); ;
            }
        }
        /// <summary>
        /// 充值成功
        /// </summary>
        /// <param name="payNo"></param>
        public void RechargeSuccess(string payNo)
        {
            using (db = DbConfig.GetInstance())
            {
                try
                {
                    db.IsNoLock = true;//启用无锁查询
                    db.CommandTimeOut = 30000;//设置超时时间
                    var model = db.Queryable<MemberRecharge>().SingleOrDefault(t => t.PayNo == payNo);
                    if (model == null)
                    {
                        throw new Exception("充值单号不存在");
                    }
                    if (model.Status == Model.Enum.OrderPayStatus.已支付)
                    {
                        throw new Exception("已充值成功");
                    }

                    var member = db.Queryable<Member>().SingleOrDefault(t => t.Id == model.MemberId);

                    db.BeginTran();//开启事务
                    if (member != null)
                    {

                        member.Balance = member.Balance + model.Amount;

                        MemberBalanceDetail mbd = new MemberBalanceDetail();
                        mbd.MemberId = member.Id;
                        mbd.Amount = model.Amount;
                        mbd.MemberAmount = member.Balance;
                        mbd.MemberPoint = member.Points;
                        mbd.Point = 0;
                        mbd.OrderId = model.Id;
                        mbd.OrderNo = "";
                        mbd.Note = "在线充值";

                        db.Insert<MemberBalanceDetail>(mbd);
                        
                        member.TotalPay = member.TotalPay + model.Amount;
                        var level = db.Queryable<MemberLevel>().Where(t => t.Id > member.MemberLevel).OrderBy(t => t.Id).FirstOrDefault();
                        if (level != null && level.Amount <= member.TotalPay)
                        {
                            member.MemberLevel = level.Id;
                        }
                        db.Update<Member>(member);
                    }
                    model.PayTime = DateTime.Now;
                    model.Status = OrderPayStatus.已支付;
                    db.Update<MemberRecharge>(model);

                    db.CommitTran();//提交事务
                }
                catch (Exception)
                {
                    db.RollbackTran();//回滚事务
                    throw;
                }
            }
        }

        #endregion


        #region 会员资金
        public List<V_MemberBalanceDetail> GetMemberBalanceDetailList(BaDetailSearchModel search, ref int total)
        {
            using (db = DbConfig.GetInstance())
            {
                var list= db.Queryable<MemberBalanceDetail>().Where(t => t.MemberId == search.MemberId).Select<MemberBalanceDetail,V_MemberBalanceDetail>("*").OrderBy(t => t.AddTime, OrderByType.Desc).ToPageList(search.Skip / search.Take + 1, search.Take, ref total);
                foreach (var item in list)
                {

                    if (item.AddUserId != null && item.AddUserId>0)
                    {
                        var user = db.Queryable<UserInfo>().FirstOrDefault(t => t.Id == item.AddUserId);
                        if (user != null)
                        {
                            item.AddUserName = user.UserName;
                        }
                    }
                }
                return list;
            }
        }

        /// <summary>
        /// 获取会员的积分记录明细
        /// </summary>
        /// <param name="memberId"></param>
        /// <returns></returns>
        public List<MemberBalanceDetail> GetMemberPointDetailList(int memberId)
        {
            using (db = DbConfig.GetInstance())
            {
                return db.Queryable<MemberBalanceDetail>().Where(t => t.MemberId == memberId && t.Point != 0).OrderBy(t => t.AddTime, OrderByType.Desc).ToList();
            }
        }

        public List<MemberBalanceDetail> GetMemberMoneyDetailList(int memberId)
        {
            using (db = DbConfig.GetInstance())
            {
                return db.Queryable<MemberBalanceDetail>().Where(t => t.MemberId == memberId && t.Amount != 0).OrderBy(t => t.AddTime, OrderByType.Desc).ToList();
            }
        }

        /// <summary>
        /// 增加资金明细
        /// </summary>
        /// <param name="model"></param>
        public void AddMemberBalanceDetail(MemberBalanceDetail model)
        {
            using (db = DbConfig.GetInstance())
            {
                var member = db.Queryable<Member>().SingleOrDefault(t => t.Id == model.MemberId);
                if (member == null)
                {
                    throw new Exception("会员不存在");
                }

                db.IsNoLock = true;//启用无锁查询
                db.CommandTimeOut = 30000;//设置超时时间
                try
                {
                    db.BeginTran();//开启事务
                    if (model.Point != 0)
                    {
                        member.Points = member.Points + model.Point;
                        if (member.Points < 0)
                        {
                            throw new Exception("积分不够");
                        }

                        model.MemberPoint = member.Points;
                    }
                    if (model.Amount != 0)
                    {
                        member.Balance = member.Balance + model.Amount;
                        if (member.Balance < 0)
                        {
                            throw new Exception("余额不足");
                        }

                        model.MemberAmount = member.Balance;
                        member.TotalPay = member.TotalPay + model.Amount;
                    }
                    db.Insert<MemberBalanceDetail>(model);
                    db.Update<Member>(member);

                    db.CommitTran();//提交事务
                }
                catch (Exception)
                {
                    db.RollbackTran();//回滚事务
                    throw;
                }
            }
        }

        #endregion

        #region 签到
        /// <summary>
        /// 签到
        /// </summary>
        /// <param name="signDate"></param>
        /// <param name="memberId"></param>
        /// <returns>连续签到天数</returns>
        public int MemberSign(DateTime signDate, int memberId)
        {
            using (db = DbConfig.GetInstance())
            {
                var sign = db.Queryable<MemberSign>().FirstOrDefault(t => t.MemberId == memberId);

                db.IsNoLock = true;//启用无锁查询
                db.CommandTimeOut = 30000;//设置超时时间
                try
                {
                    db.BeginTran();//开启事务
                    if (sign == null)
                    {
                        sign = new MemberSign();
                        sign.MemberId = memberId;
                        sign.SignCount = 1;
                        sign.TotalSignCount = 1;
                        sign.SignDate = signDate.Date;
                        db.Insert<MemberSign>(sign);

                    }
                    else
                    {
                        if (sign.SignDate.Date == signDate.Date)
                        {
                            throw new Exception("今日已签到");
                        }
                        else if (sign.SignDate.AddDays(1) == signDate.Date)
                        {
                            sign.SignCount = sign.SignCount + 1;
                        }
                        else
                        {
                            sign.SignCount = 1;
                        }
                        sign.TotalSignCount = sign.TotalSignCount + 1;
                        sign.SignDate = signDate.Date;
                        db.Update<MemberSign>(sign);
                    }

                    var member = db.Queryable<Member>().SingleOrDefault(t => t.Id == memberId);
                    var level = db.Queryable<MemberLevel>().FirstOrDefault(t => t.Id == member.MemberLevel);
                    member.Points = member.Points + level.SignPoint;
                    db.Update<Member>(member);
                    if (level.SignPoint > 0)
                    {
                        MemberBalanceDetail mbd = new MemberBalanceDetail();
                        mbd.AddUserId = 0;
                        mbd.Amount = 0;
                        mbd.Point = level.SignPoint;
                        mbd.MemberAmount = member.Balance;
                        mbd.MemberPoint = member.Points;
                        mbd.MemberId = member.Id;
                        mbd.Note = "签到积分";
                        db.Insert<MemberBalanceDetail>(mbd);
                    }

                    db.CommitTran();//提交事务
                    return sign.SignCount;
                }
                catch (Exception)
                {
                    db.RollbackTran();//回滚事务
                    throw;
                }
            }
        }
        #endregion

        #region 搜索历史

        public List<Member_SearchHistory> SearchHistoryList(int Skip, int Take, int currentMemberId, out int total)
        {
            using (db = DbConfig.GetInstance())
            {
                total = db.Queryable<Member_SearchHistory>().Where(m => m.MemberId == currentMemberId).Count();
                return db.Queryable<Member_SearchHistory>().Where(m => m.MemberId == currentMemberId).OrderBy(o => o.EditTime, OrderByType.Desc).Skip(Skip).Take(Take).ToList();
            }
        }

        public Result AddSearchHistory(int currentMemberId, string keywords)
        {
            using (db = DbConfig.GetInstance())
            {
                if (db.Queryable<Member_SearchHistory>().Where(m => m.MemberId == currentMemberId && m.Keywords == keywords).Count() > 0)
                {
                    db.Update<Member_SearchHistory>(new { EditTime = DateTime.Now, EditUserId = currentMemberId }, m => m.MemberId == currentMemberId && m.Keywords == keywords);
                }
                else
                {
                    db.Insert(new Member_SearchHistory { MemberId = currentMemberId, Keywords = keywords, AddUserId = currentMemberId });
                }
                return Result.Success();
            }
        }

        public Result DelSearchHistory(int currentMemberId)
        {
            using (db = DbConfig.GetInstance())
            {
                db.Update<Member_SearchHistory>(new { EditTime = DateTime.Now, EditUserId = currentMemberId, IsDeleted = true }, m => m.MemberId == currentMemberId);
                return Result.Success();
            }
        }

        #endregion


        /// <summary>
        /// 统计新增会员
        /// </summary>
        /// <returns></returns>
        public int GetAddMember()
        {
            using (db = DbConfig.GetInstance())
            {
                var t1 = Convert.ToDateTime(DateTime.Now.ToShortDateString());
                var t2 = Convert.ToDateTime(DateTime.Now.AddDays(1).ToShortDateString());

                var list = db.Queryable<Model.Member>()
                   .Where(m => m.AddTime > t1 && m.AddTime < t2)
                   .ToList();
               
                return list.Count;
            }
        }
    }
}
